﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using GeneratorLib.DB;
using GeneratorLib.DB.Connectios;
using GeneratorLib.DB.Schemas;
using Generator.CusEventArgs;

namespace Generator
{
    public partial class FrmMain : Form
    {

        private ConnectionInfos _connectionInfos;

        public FrmMain()
        {
            InitializeComponent();
            _connectionInfos = ConnectionInfos.Read();
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            loadConnectionInfos();
            loadTemplateFiles();
        }

        private void loadConnectionInfos()
        {
            trvConnections.Nodes.Clear();
            foreach (var info in _connectionInfos.Connections)
            {
                AddConnectionInfo(info);
            }
        }

        private void loadTemplateFiles()
        {
            string templateFileRoot = GlobalValues.CurrentPath + "/TemplateFiles";
            if (!Directory.Exists(templateFileRoot))
            {
                Directory.CreateDirectory(templateFileRoot);
            }
            DirectoryInfo di = new DirectoryInfo(templateFileRoot);

            templateFilesToolStripMenuItem.DropDownItems.Clear();
            addTemplateToMenu(templateFilesToolStripMenuItem, di);
        }

        private void addTemplateToMenu(ToolStripMenuItem parentMenu, DirectoryInfo direcory)
        {
            bool bl = false;
            foreach (DirectoryInfo di in direcory.GetDirectories())
            {
                ToolStripMenuItem item = (ToolStripMenuItem)parentMenu.DropDownItems.Add(di.Name);
                addTemplateToMenu(item, di);
                bl = true;
            }

            foreach (FileInfo fi in direcory.GetFiles("*.cmt"))
            {
                if (bl)
                    parentMenu.DropDownItems.Add(new ToolStripSeparator());
                bl = false;
                Generator.TemplateGenerators.TemplateFile file = new TemplateGenerators.TemplateFile(fi.FullName);
                ToolStripMenuItem item = (ToolStripMenuItem)parentMenu.DropDownItems.Add(file.TemplateName);
                item.Image = global::Generator.Properties.Resources.New16;
                item.ImageTransparentColor = System.Drawing.Color.Magenta;
                item.Tag = file;
                item.Click += new EventHandler(item_Click);
            }
        }

        void item_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem item = (ToolStripMenuItem)sender;
            Generator.TemplateGenerators.TemplateFile file = item.Tag as Generator.TemplateGenerators.TemplateFile;

            TreeNode node = trvConnections.SelectedNode;
            TemplateGenerators.TemplateGenerator frmTable = new TemplateGenerators.TemplateGenerator();
            ShowGeneratorForm(node, frmTable, file);

        }

        #region Menu method

        private void AddConnectionInfo(IConnection info)
        {
            TreeNode node = trvConnections.Nodes.Add(info.Name);
            node.ImageIndex = 0;
            node.SelectedImageIndex = 0;
            node.Tag = info;
            //trvConnections.SelectedNode = node;
            //tmConnectDB_Click(node, EventArgs.Empty);
        }

        private void tmAddSQLServerConnector_Click(object sender, EventArgs e)
        {
            SQLServer2008Connection info = new SQLServer2008Connection("SQLServer2008", "");

            DBConnecter frmCon = new DBConnecter();
            frmCon.ConnectionInfo = info;
            DialogResult res = frmCon.ShowDialog();
            if (res != DialogResult.OK) return;

            _connectionInfos.AddItem(frmCon.ConnectionInfo);
            AddConnectionInfo(frmCon.ConnectionInfo);

        }

        private void tmAddMYSQLConnector_Click(object sender, EventArgs e)
        {
            MYSQLConnection info = new MYSQLConnection("MYSQL", "");

            DBConnecter frmCon = new DBConnecter();
            frmCon.ConnectionInfo = info;
            DialogResult res = frmCon.ShowDialog();
            if (res != DialogResult.OK) return;

            _connectionInfos.AddItem(frmCon.ConnectionInfo);
            AddConnectionInfo(frmCon.ConnectionInfo);
        }

        private void tmConnectDB_Click(object sender, EventArgs e)
        {
            TreeNode node = trvConnections.SelectedNode;
            if (node == null) return;
            if (node.Nodes.Count > 0) return;
            IConnection conInfo = node.Tag as IConnection;
            if (conInfo != null)
            {
                List<TableInfo> tables = conInfo.Tables;
                foreach (var table in tables)
                {
                    TreeNode n = node.Nodes.Add(table.TableName);
                    n.Tag = table;
                    n.ImageIndex = 1;
                    n.SelectedImageIndex = 1;

                }
                node.ExpandAll();
            }
        }

        private void tmTableInfoGenerator_Click(object sender, EventArgs e)
        {

            TreeNode node = trvConnections.SelectedNode;
            Generators.TableFieldList frmTable = new Generators.TableFieldList();
            frmTable.ShowEditRelationClickedHandler += (obj, arg) =>
            {
                ShowEditRelationFrm(arg);
            };
            frmTable.ShowEditTableInfomationClickedHandler += (obj, arg) =>
            {
                ShowEditTableInfomationFrm(arg);
            };
            frmTable.TableAddinChangedHandler += (obj, arg) =>
            {
                SaveConnections();
            };
            ShowGeneratorForm(node, frmTable);


            //TreeNode node = trvConnections.SelectedNode;
            //if (node == null) return;
            //if (node.Tag == null) return;

            //TableInfo table = node.Tag as TableInfo;
            //Generators.TableFieldList frmTable = new Generators.TableFieldList();
            //frmTable.ShowEditRelationClickedHandler += (obj, arg) =>
            //{
            //    ShowEditRelationFrm(arg);
            //};
            //frmTable.ShowEditTableInfomationClickedHandler += (obj, arg) =>
            //{
            //    ShowEditTableInfomationFrm(arg);
            //};
            //frmTable.TableAddinChangedHandler += (obj, arg) =>
            //{
            //    SaveConnections();
            //};
            //frmTable.Connection = node.Parent.Tag as IConnection;
            //frmTable.Table = table;

            //AddGeneratorBaseForm(frmTable);

        }

        private void tmServerControllerGenerator_Click(object sender, EventArgs e)
        {
            TreeNode node = trvConnections.SelectedNode;
            Generators.GeneratorBase frmTable = null;
            TableInfo table = node.Tag as TableInfo;
            if (table == null) return;

            if (table.Connection is MYSQLConnection)
                frmTable = new Generators.ServerController_MySQL();
            else if (table.Connection is SQLServer2008Connection)
                frmTable = new Generators.ServerController_SQLServer();
            else if (table.Connection is SQLServer2005Connection)
                frmTable = new Generators.ServerController_SQLServer();
            else
                frmTable = new Generators.GeneratorBase();

            ShowGeneratorForm(node, frmTable);


            //TreeNode node = trvConnections.SelectedNode;
            //if (node == null) return;
            //if (node.Tag == null) return;

            //TableInfo table = node.Tag as TableInfo;
            //Generators.ServerController frmTable = new Generators.ServerController();
            //frmTable.Connection = node.Parent.Tag as IConnection;
            //frmTable.Table = table;

            //AddGeneratorBaseForm(frmTable);
        }

        private void tmMVCEditModelGenerator_Click(object sender, EventArgs e)
        {
            TreeNode node = trvConnections.SelectedNode;
            Generators.MVCEditModel frmTable = new Generators.MVCEditModel();
            ShowGeneratorForm(node, frmTable);

            //TreeNode node = trvConnections.SelectedNode;
            //if (node == null) return;
            //if (node.Tag == null) return;

            //TableInfo table = node.Tag as TableInfo;
            //Generators.MVCEditModel frmTable = new Generators.MVCEditModel();
            //frmTable.Connection = node.Parent.Tag as IConnection;
            //frmTable.Table = table;

            //AddGeneratorBaseForm(frmTable);
        }

        private void tmMVCListModelGenerator_Click(object sender, EventArgs e)
        {
            TreeNode node = trvConnections.SelectedNode;
            Generators.MVCListModel frmTable = new Generators.MVCListModel();
            ShowGeneratorForm(node, frmTable);
        }


        private void tmMVCControllerGenerator_Click(object sender, EventArgs e)
        {
            TreeNode node = trvConnections.SelectedNode;
            Generators.MVCController frmTable = new Generators.MVCController();
            ShowGeneratorForm(node, frmTable);
        }

        private void tmMVCViewGenerator_Click(object sender, EventArgs e)
        {
            TreeNode node = trvConnections.SelectedNode;
            Generators.MVCView frmTable = new Generators.MVCView();
            ShowGeneratorForm(node, frmTable);
        }

        #endregion

        private void ShowGeneratorForm(TreeNode node, Generators.GeneratorBase frmTable)
        {
            if (node == null) return;
            if (node.Tag == null) return;
            TableInfo table = node.Tag as TableInfo;
            if (table == null) return;

            frmTable.Connection = node.Parent.Tag as IConnection;
            frmTable.Table = table;
            frmTable.Generate();

            AddInnerFormToPanel(frmTable);
        }

        private void ShowToolsForm(Tools.ToolsBase frmTable)
        {
            AddInnerFormToPanel(frmTable);
        }



        private void ShowGeneratorForm(TreeNode node, TemplateGenerators.TemplateGenerator frmTable, Generator.TemplateGenerators.TemplateFile templateFile)
        {
            if (node == null) return;
            if (node.Tag == null) return;
            TableInfo table = node.Tag as TableInfo;
            if (table == null) return;

            frmTable.Connection = node.Parent.Tag as IConnection;
            frmTable.Table = table;
            frmTable.TemplateFile = templateFile;
            //frmTable.Generate();

            frmTable.TemplateFileAdded += (obj, e) =>
            {
                loadTemplateFiles();
            };

            AddInnerFormToPanel(frmTable);
        }

        private void AddInnerFormToPanel(System.Windows.Forms.Form frmTable)
        {
            panGenerator.Controls.Clear();
            panGenerator.Controls.Add(frmTable);

            frmTable.Left = 0;
            frmTable.Top = 0;
            frmTable.Width = panGenerator.Width;
            frmTable.Height = panGenerator.Height;
            frmTable.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom;
            frmTable.Visible = true;

        }


        private void ShowEditRelationFrm(TableSelectedEventArg arg)
        {
            FrmDBRelationEdit edit = new FrmDBRelationEdit();
            if (arg.Field != null)
            {
                edit.Field = arg.Field;
            }
            else
            {
                edit.Table = arg.Table;
            }

            DialogResult res = edit.ShowDialog();
            if (res != DialogResult.OK)
                return;

            IConnection con = arg.Table.Connection;
            Relation r = edit.RelationShip;
            try
            {
                con.AddRelation(r);
                _connectionInfos.Save();
                arg.Result = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void ShowEditTableInfomationFrm(TableSelectedEventArg arg)
        {
            FrmTableAddinEdit edit = new FrmTableAddinEdit();
            TableInfoAddin tableAddin = arg.Table.Connection.FindTableAddin(arg.Table.TableName);
            edit.TableAddin = tableAddin;
            DialogResult res = edit.ShowDialog(this);
            if (res != DialogResult.OK) return;

            try
            {
                _connectionInfos.Save();
                arg.Result = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void SaveConnections()
        {
            try
            {
                _connectionInfos.Save();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void trvConnections_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != System.Windows.Forms.MouseButtons.Right) return;
            TreeViewHitTestInfo testInfo = trvConnections.HitTest(e.X, e.Y);
            if (testInfo.Node == null) return;

            trvConnections.SelectedNode = testInfo.Node;

            IConnection conInfo = testInfo.Node.Tag as IConnection;
            if (conInfo != null)
            {
                cmDBConnection.Show(trvConnections, e.X, e.Y);
                return;
            }

            TableInfo table = testInfo.Node.Tag as TableInfo;
            if (table != null)
            {
                cmTableInfo.Show(trvConnections, e.X, e.Y);
                return;
            }


        }

        private void panGenerator_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != System.Windows.Forms.MouseButtons.Right) return;
            if (trvConnections.SelectedNode == null) return;
            TableInfo table = trvConnections.SelectedNode.Tag as TableInfo;
            if (table != null)
            {
                cmTableInfo.Show(panGenerator, e.X, e.Y);
                return;
            }
        }

        private void FrmMain_MouseDown(object sender, MouseEventArgs e)
        {

        }

        private void check_MouseDown(IntPtr ptr)
        {
            byte[] bytes = BitConverter.GetBytes(ptr.ToInt32());
            Point p = new Point(bytes[0] + bytes[1] * 255, bytes[2] + bytes[3] * 255);

        }



        /*
        private const int WM_RBUTTONDOWN = 0x204;
        private const int WM_RBUTTONDOWN2 = 0x7b;
        protected override void WndProc(ref Message m)
        {

            switch (m.Msg)
            {
                case WM_RBUTTONDOWN:
                case WM_RBUTTONDOWN2:
                    check_MouseDown(m.LParam);
                    break;
                default:
                    break;
            }
            base.WndProc(ref m);
            
        }
        */

        private void trvConnections_AfterSelect(object sender, TreeViewEventArgs e)
        {

        }

        private void trvConnections_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            TreeViewHitTestInfo testInfo = trvConnections.HitTest(e.X, e.Y);
            if (testInfo.Node == null) return;

            trvConnections.SelectedNode = testInfo.Node;

            IConnection conInfo = testInfo.Node.Tag as IConnection;
            if (conInfo != null && testInfo.Node.Nodes.Count == 0)
            {
                tmConnectDB_Click(cmDBConnection.Items[0], EventArgs.Empty);
                return;
            }

            TableInfo table = testInfo.Node.Tag as TableInfo;
            if (table != null)
            {
                tmTableInfoGenerator_Click(cmTableInfo.Items[0], EventArgs.Empty);
                return;
            }


        }

        private void tmRemoveConnection_Click(object sender, EventArgs e)
        {
            TreeNode node = trvConnections.SelectedNode;
            if (node == null) return;
            IConnection conInfo = node.Tag as IConnection;
            if (conInfo != null)
            {
                _connectionInfos.RemoveItem(conInfo);
                trvConnections.Nodes.Remove(node);
                _connectionInfos.Save();
            }

        }

        private void tmClearAllRelations_Click(object sender, EventArgs e)
        {
            TreeNode node = trvConnections.SelectedNode;
            if (node == null) return;
            IConnection conInfo = node.Tag as IConnection;
            if (conInfo != null)
            {
                conInfo.ClearRelation();
                _connectionInfos.Save();
                RefreshGenerator();
            }
        }

        private void tmQuit_Click(object sender, EventArgs e)
        {
            this.Close();
            //Application.Exit();
            Environment.Exit(Environment.ExitCode);
        }

        private void tbRemoveTableAllRelations_Click(object sender, EventArgs e)
        {
            TreeNode node = trvConnections.SelectedNode;
            if (node == null) return;
            var table = node.Tag as TableInfo;
            if (table != null)
            {
                table.Connection.ClearRelation(table);
                _connectionInfos.Save();
                RefreshGenerator();
            }

        }

        private void RefreshGenerator()
        {
            if (panGenerator.Controls.Count > 0)
            {
                var frm = panGenerator.Controls[0] as Generators.GeneratorBase;
                if (frm != null)
                    frm.Generate();
            }
        }

        private void tmConnectionEdit_Click(object sender, EventArgs e)
        {
            TreeNode node = trvConnections.SelectedNode;
            if (node == null) return;
            var conInfo = node.Tag as IConnection;
            if (conInfo == null) return;

            var frmCon = new DBConnecter();
            frmCon.ConnectionInfo = conInfo;
            DialogResult res = frmCon.ShowDialog();
            if (res != DialogResult.OK) return;
            {
                conInfo = frmCon.ConnectionInfo;
                node.Text = conInfo.Name;
                node.Tag = conInfo;
                _connectionInfos.Save();
            }
        }

        private void tmTemplateGenerator_Click(object sender, EventArgs e)
        {
            TreeNode node = trvConnections.SelectedNode;
            var frmTable = new TemplateGenerators.TemplateGenerator();
            ShowGeneratorForm(node, frmTable, null);

        }

        private void tmSave_Click(object sender, EventArgs e)
        {
            if (panGenerator.Controls.Count == 0)
            {
                return;
            }

            var generator = panGenerator.Controls[0] as Generators.GeneratorBase;
            if (generator == null)
            {
                return;
            }

            generator.Save();

        }

        private void tmBatchGenerator_Click(object sender, EventArgs e)
        {
            TreeNode node = trvConnections.SelectedNode;
            if (node == null) return;
            var conInfo = node.Tag as IConnection;
            if (conInfo == null) return;

            var frmCon = new BatchGenerator();
            frmCon.ConnectionInfo = conInfo;
            DialogResult res = frmCon.ShowDialog();
        }

        private void tmRefreshConnection_Click(object sender, EventArgs e)
        {
            TreeNode node = trvConnections.SelectedNode;
            if (node == null) return;
            //if (node.Nodes.Count > 0) return;
            var conInfo = node.Tag as IConnection;
            if (conInfo != null)
            {
                conInfo.Reset();
                node.Nodes.Clear();

                tmConnectDB_Click(sender, e);
            }
        }

        private void sQLConvertToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var frm = new Tools.SQLConvert();
            ShowToolsForm(frm);
        }

        private void convertAssemblyToMonoTouchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var frm = new Tools.ConvertServerControllerToMonoTouch();
            ShowToolsForm(frm);
        }

        private void stringFormatToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var frm = new Tools.StringFormat();
            ShowToolsForm(frm);

        }

        private void wSTestToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var frm = new Tools.WSTest();
            ShowToolsForm(frm);
        }

        private void encodingConvertToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var frm = new Tools.EncodeConvert();
            ShowToolsForm(frm);
        }

        private void clearLicxToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var frm = new Tools.ClearLicx();
            ShowToolsForm(frm);
        }

        private void closeFormToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var frm = new Tools.CloseForm();
            ShowToolsForm(frm);
        }

        private void pDBReaderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var frm = new Tools.PDBReader();
            ShowToolsForm(frm);
        }

        private void regexTestToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var frm = new Tools.RegexTest();
            ShowToolsForm(frm);
        }
    }
}
